package dubbo

import (
	"context"
	"log"
	"os"
	"time"

	_ "github.com/apache/dubbo-go/common/proxy/proxy_factory"
	"github.com/apache/dubbo-go/config"
	_ "github.com/apache/dubbo-go/protocol/dubbo"
	_ "github.com/apache/dubbo-go/registry/protocol"

	_ "github.com/apache/dubbo-go/filter/filter_impl"

	"daxin.my/test-netserver/api"
	"daxin.my/test-netserver/protocol/dubbo/model"
	"daxin.my/test-netserver/protocol/dubbo/service"
	_ "github.com/apache/dubbo-go/cluster/cluster_impl"
	_ "github.com/apache/dubbo-go/cluster/loadbalance"
	_ "github.com/apache/dubbo-go/registry/zookeeper"
)

type DubboClient struct {
	ConsumerService *service.DubboServiceConsumer
	state           int32 // 当前发送消息状态， 0. 正常 1. 慢
}

func InitDubboClient() *DubboClient {
	consumeFile := os.Getenv("CONF_CONSUMER_FILE_PATH")
	if len(consumeFile) == 0 {
		panic("Please Specify CONF_CONSUMER_FILE_PATH in Environment.")
	}

	service := new(service.DubboServiceConsumer)
	config.SetConsumerService(service)

	config.Load()
	time.Sleep(3 * time.Second)
	log.Println("Start Dubbo Client")

	return &DubboClient{
		ConsumerService: service,
		state:           0,
	}
}

// need to setup environment variable "CONF_CONSUMER_FILE_PATH" to "conf/client.yml" before run
func (c *DubboClient) Request(param api.RequestParam) {
	request := &model.RequestData{
		Sleep:        param.Sleep,
		ResponseByte: param.ResponseByteNum,
		Payload:      string(make([]byte, param.RequestByteNum)),
	}
	response := &model.ResponseData{}
	startTime := time.Now()
	err := c.ConsumerService.Request(context.Background(), request, response)
	if err != nil {
		log.Printf("Dubbo Client Failed: %v\n", err)
		return
	}
	duration := time.Since(startTime)
	log.Printf("Dubbo Client Success. request size = %d, response size = %d, cost %dms",
		param.RequestByteNum, len(response.Message), duration.Milliseconds())
}

func (client *DubboClient) Visit() {
	requestParam := api.RequestParam{
		Sleep:           0,
		StatusCode:      200,
		RequestByteNum:  10,
		ResponseByteNum: 10,
	}

	switch client.state {
	case 1:
		requestParam.Sleep = 500
		client.state = 0
	default:
		client.state = 1
	}
	client.Request(requestParam)
}

func (c *DubboClient) Close() {
}
